package com.ruoyi.qywx.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ruoyi.common.core.cache.Meta;
import com.ruoyi.common.utils.CollectionUtils;
import com.ruoyi.common.utils.StrUtils;
import com.ruoyi.qywx.callback.txl.ExternalUserEncrypt;
import com.ruoyi.qywx.entity.ExtContact;
import com.ruoyi.qywx.entity.ExtFollowContact;
import com.ruoyi.qywx.entity.ExtUserTag;
import com.ruoyi.qywx.getway.api.ExternalcontactApi;
import com.ruoyi.qywx.getway.dto.QyExtContactDto;
import com.ruoyi.qywx.getway.entity.QyExtContactRemark;
import com.ruoyi.qywx.getway.entity.QyExternalContact;
import com.ruoyi.qywx.getway.entity.QyExternalUserTag;
import com.ruoyi.qywx.getway.entity.QyFollowUser;
import com.ruoyi.qywx.mapper.ExtContactMapper;
import com.ruoyi.qywx.model.vo.BindTagVo;
import com.ruoyi.qywx.model.vo.TagGroupVo;
import com.ruoyi.qywx.model.vo.TagVo;
import com.ruoyi.qywx.model.vo.CustomerFollowerVo;
import com.ruoyi.qywx.service.inters.ContactTagServic;
import com.ruoyi.qywx.service.inters.ExtContactService;
import com.ruoyi.qywx.service.inters.ExtFollowContactService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author : hcl
 * @Date : 2023/8/22 16:05
 */
@Service
public class ExtContactServiceImpl implements ExtContactService {
    @Resource
    private ExtContactMapper extContactMapper;
    @Autowired
    private ExtFollowContactService followContactService;
    @Autowired
    private ContactTagServic contactTagServic;

    @Override
    public ExtContact selectContactById(Long id) {
        return extContactMapper.selectById(id);
    }

    /**
     * 添加外部客户
     * 绑定标签 || 备注
     * 丢MQ 最好，条件不允许，木有MQ
     */
    @Override
    public void addExternalContact(ExternalUserEncrypt encrypt, String bindTags,
                                   String remark, Meta meta, ContactTagServic tagServic) {
        String cursor = "";
        while (cursor != null) {
            QyExtContactDto extContactDto = ExternalcontactApi.externalcontactGet(meta, encrypt.getExternalUserID(), cursor);
            if (Objects.isNull(extContactDto)) {
                break;
            }
            QyExternalContact extContact = extContactDto.getExternal_contact();
            QyFollowUser find = extContactDto.getFollow_user().stream()
                    .filter(f -> f.getUserid().equals(encrypt.getUserID()))
                    .peek(f -> {
                        if (StrUtils.isNotEmpty(remark)) {
                            // 绑定备注信息,这里不更新库，用户可能未存在于库中
                            boolean success = followContactService.updateExtUserRemark(
                                    QyExtContactRemark.builder()
                                            .external_userid(extContact.getExternal_userid())
                                            .userid(f.getUserid())
                                            .remark(remark)
                                            .build()
                                    , meta,
                                    false
                            );
                            if (success) f.setRemark(remark);
                        }
                    }).findFirst().orElse(null);
            if (Objects.nonNull(find)) {
                ExtContact contact = extContact.getExternalContact(meta.getTeamId());
                insertExtContact(contact);
                ExtFollowContact follower = find.getExternalFollower(extContact.getExternal_userid());
                followContactService.insertFollower(follower);
                // 绑定标签
                tagServic.extUserBindTags(follower.getExtUserId(), follower.getUserId(), CollectionUtils.toLongList(bindTags), meta);
                // 用户本身标签处理
//                tagServic.extContactTagsProcess(follower.getExtUserId(),follower.getUserId(),find.getTags(),meta);
                break;
            }
            if (StrUtils.isEmpty(extContact.getNext_cursor())) {
                break;
            }
            cursor = extContact.getNext_cursor();
        }
    }

    @Transactional
    public void insertExtContact(ExtContact contact) {
        if (Objects.isNull(contact)) return;
        ExtContact extContact = extContactMapper.selectOne(new QueryWrapper<ExtContact>()
                .eq("team_id", contact.getTeamId())
                .eq("ext_user_id", contact.getExtUserId())
        );
        if (Objects.nonNull(extContact)) {
            UpdateWrapper<ExtContact> update = new UpdateWrapper<>();
            if (contact.getAvatar() != null && !StrUtils.equals(contact.getAvatar(), extContact.getAvatar())) {
                update.set("avatar", contact.getAvatar());
            }
            if (contact.getPosition() != null && !StrUtils.equals(contact.getPosition(), extContact.getPosition())) {
                update.set("position", contact.getPosition());
            }
            if (contact.getCorpName() != null && !StrUtils.equals(contact.getCorpName(), extContact.getCorpName())) {
                update.set("corp_name", contact.getCorpName());
            }
            if (contact.getCorpFullName() != null && !StrUtils.equals(contact.getCorpFullName(), extContact.getCorpFullName())) {
                update.set("corp_full_name", contact.getCorpFullName());
            }
            if (extContact.getIsDelete()) {
                update.set("is_delete", false);
            }
            if (StrUtils.isNotEmpty(update.getSqlSet())) {
                update.eq("id", extContact.getId());
                extContactMapper.update(contact, update);
            }
        } else {
            extContactMapper.insert(contact);
        }
    }

    /**
     * 非Api方式编辑用户信息时，需要更新库数据
     */
    @Override
    public void editExternalContact(ExternalUserEncrypt encrypt, Meta meta, ContactTagServic tagServic) {
        String cursor = "";
        while (cursor != null) {
            QyExtContactDto extContactDto = ExternalcontactApi.externalcontactGet(meta, encrypt.getExternalUserID(), cursor);
            if (Objects.isNull(extContactDto)) {
                break;
            }
            QyExternalContact extContact = extContactDto.getExternal_contact();
            QyFollowUser find = extContactDto.getFollow_user().stream()
                    .filter(f -> f.getUserid().equals(encrypt.getUserID()))
                    .peek(f -> {
                        followContactService.updateFollowerRemark(
                                QyExtContactRemark.builder()
                                        .external_userid(extContact.getExternal_userid())
                                        .userid(f.getUserid())
                                        .remark(f.getRemark())
                                        .remark_mobiles(f.getRemark_mobiles())
                                        .description(f.getDescription())
                                        .build()
                        );
                    }).findFirst().orElse(null);
            // 标签入库
            List<QyExternalUserTag> followerTags = null;
            if (CollectionUtils.isNotEmpty(find.getTags())) {
                followerTags = find.getTags().stream()
                        .filter(tag -> StrUtils.isNotEmpty(tag.getTag_id())).collect(Collectors.toList());
            }
            tagServic.extContactTagsProcess(encrypt.getExternalUserID(), encrypt.getUserID(), followerTags, meta);
            if (StrUtils.isEmpty(extContact.getNext_cursor())) {
                break;
            }
            cursor = extContact.getNext_cursor();
        }
    }

    @Transactional
    @Override
    public void deleteExternalContact(String externalUserId, String userId, Long teamId) {
        followContactService.deleteExternalContact(externalUserId, userId);
        externalContactLost(externalUserId, teamId);
    }

    @Transactional
    @Override
    public void deleteFollower(String externalUserId, String userID, Long teamId) {
        followContactService.deleteFollower(externalUserId, userID);
        externalContactLost(externalUserId, teamId);
    }

    /**
     * 查询是否还有跟进员工
     * 若没有则删除该外部联系人
     */
    @Transactional
    public void externalContactLost(String extUserId, Long teamId) {
        if (StrUtils.isEmpty(extUserId)) return;
        boolean allLost = followContactService.isAllLost(extUserId);
        if (allLost) {
            extContactMapper.update(null, new UpdateWrapper<ExtContact>()
                    .set("is_delete", true)
                    .eq("ext_user_id", extUserId)
                    .eq("team_id", teamId));
        }
    }

    @Override
    public List<Long> simpleTmAndNameQueryExtConcatIds(String concatName, Long teamId) {
        QueryWrapper<ExtContact> query = new QueryWrapper<>();
        if (StrUtils.isNotEmpty(concatName)) {
            query.like("name", concatName);
        }
        query.eq("team_id", teamId)
                .orderByDesc("id");
        return extContactMapper.findIds(query);
    }

    @Override
    public List<CustomerFollowerVo> selectFollowersByContactId(String extUserId) {
        List<CustomerFollowerVo> vos = followContactService.selectFollowersByExtUserId(extUserId);
        if (CollectionUtils.isEmpty(vos)) {
            return Collections.emptyList();
        }
        List<String> userIds = vos.stream().map(CustomerFollowerVo::getUserId).collect(Collectors.toList());
        List<ExtUserTag> tags = contactTagServic.selectFollowerTags(Collections.singletonList(extUserId), userIds);
        Map<String, List<ExtUserTag>> userTagMaps = tags.stream()
                .collect(Collectors.groupingBy(ExtUserTag::getUserId));
        // userID -> TagGroupVo
        Map<String, List<TagGroupVo>> userGroupTags = userTagMaps.entrySet()
                .stream()
                .collect(Collectors.toMap(Map.Entry::getKey,
                        t -> t.getValue()
                                .stream()
                                .collect(Collectors.groupingBy(ExtUserTag::getGroupName))
                                .entrySet()
                                .stream()
                                .map(tag -> {
                                    TagGroupVo groupVo = new TagGroupVo();
                                    groupVo.setName(tag.getKey());
                                    groupVo.setTags(
                                            tag.getValue()
                                                    .stream()
                                                    .map(eut -> new TagVo(eut.getTagId(), eut.getTagName()))
                                                    .collect(Collectors.toList())
                                    );
                                    return groupVo;
                                }).collect(Collectors.toList())
                ));
        for (CustomerFollowerVo vo : vos) {
            vo.setGroups(userGroupTags.getOrDefault(vo.getUserId(), Collections.emptyList()));
        }
        return vos;
    }

    @Override
    public boolean bindFollowerTags(BindTagVo bind, Meta meta) {
        if (StrUtils.isEmpty(bind.getTags())) return false;
        Map<String, String> follower = extContactMapper.findFollower(bind.getId(),
                bind.getUserId(),
                meta.getTeamId());
        if (follower == null) return false;
        return contactTagServic.extUserBindTags(follower.get("extUserId"),
                bind.getUserId(),
                CollectionUtils.toLongList(bind.getTags()),
                meta);
    }

    @Override
    public ExtFollowContact selectFollower(String extUserId, String userId) {
        List<ExtFollowContact> followers = followContactService.selectFollower(extUserId, userId);
        return CollectionUtils.isEmpty(followers) ? null : followers.get(0);
    }

    @Override
    public void updateFollowerById(QyExtContactRemark remark) {
        followContactService.updateFollowerRemark(remark);
    }
}
